import java.util.SortedMap;
import java.util.TreeMap;

public class ConsistentHashWithVirtual {

    /**
     * 负载均衡（根据IP 路由到 指定服务器）
     *      2、一致性hash算法 （无虚拟节点）
     */
    public static void main(String[] args) {
        // 服务端IP
        String[] servers = new String[]{"120.6.1.44", "145.33.15.234", "43.144.65.64", "12.133.144.55", "99.88.127" +
                ".111"};
        // 可排序的Map
        SortedMap<Integer, String> hashServerMaps = new TreeMap<>();

        // 每个实际节点产生的虚拟节点数量
        int virtualCount = 3;

        for (String server : servers){
            int serverHash = Math.abs(server.hashCode());
            hashServerMaps.put(serverHash, server);

            for(int i = 0; i < virtualCount; i++){
                int virtualHash = Math.abs((server + "#" + i).hashCode());
                hashServerMaps.put(virtualHash, "由虚拟节点" + i + "路由到" + server);
            }
        }


        // 客户端IP
        String[] clients = new String[]{"123.10.1.44", "145.33.5.234", "243.144.65.64", "112.33.44.55", "99.88.27" +
                ".111"};
        for (String client : clients){
            int clientHash = Math.abs(client.hashCode());
            // tailMap(key)：获取比key大的集合
            SortedMap<Integer, String> tailMap = hashServerMaps.tailMap(clientHash);
            if(tailMap.isEmpty()){
                // 如果为空，则取原集合第一个元素
                Integer integer = hashServerMaps.firstKey();
                System.out.println(client + " 路由到 " + hashServerMaps.get(integer) + "上。");
            } else {
                // 不为空，取当前集合的第一个元素
                Integer integer = tailMap.firstKey();
                System.out.println(client + " 路由到 " + hashServerMaps.get(integer) + "上。");
            }
        }
    }
}
